package com.lcq.demo.controller;

import com.google.common.base.Preconditions;
import com.lcq.demo.common.entity.Result;
import com.lcq.demo.common.enums.BucketNameEnum;
import com.lcq.demo.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

import static com.lcq.demo.common.enums.BucketNameEnum.TEST_BUCKET_NAME;

/**
 * @author 240701005
 */
@Tag(name = "文件管理")
@RestController
@RequestMapping("/api/file")
@Slf4j
//@CrossOrigin(origins = "*", allowedHeaders = "token")
public class FileController {

    @Resource
    private FileService fileService;

    /**
     * 查询指定目录下文件列表
     */
    @Operation(summary = "查询指定目录下文件列表")
    @GetMapping("/list")
    public Result<List<String>> listFiles(@RequestParam String directory) {
        try {
            if (log.isInfoEnabled()) {
                log.info("FileController.listFiles.directory：{}", directory);
            }
            Preconditions.checkNotNull(directory, "目录不能为空！");
            return Result.ok(fileService.listFiles(directory));
        } catch (Exception e) {
            log.error("FileController.listFiles.error:{}", e.getMessage(), e);
            return Result.fail("查看文件列表失败！");
        }
    }

    /**
     * 上传文件
     */
    @Operation(summary = "上传文件")
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Result<String> uploadFile(@RequestPart("file") MultipartFile file, @RequestParam(name = "fileName") String fileName) {
        try {
            if (log.isInfoEnabled()) {
                log.info("FileController.uploadFile.bucketName:{}", TEST_BUCKET_NAME.bucketName);
            }
            Preconditions.checkNotNull(file, "文件不能为空！");
            Preconditions.checkArgument(!StringUtils.isEmpty(fileName), "文件名不能为空！");
            return Result.ok(fileService.uploadFile(file, fileName, TEST_BUCKET_NAME.bucketName));
        } catch (Exception e) {
            log.error("FileController.uploadFile.error:{}", e.getMessage(), e);
            return Result.fail("上传文件失败！");
        }
    }

    /**
     * 下载文件
     */
    @Operation(summary = "下载文件")
    @GetMapping("/download")
    public ResponseEntity<InputStreamResource> downloadFile(@RequestParam String fileName, HttpServletRequest request) {
        try {
            if (log.isInfoEnabled()) {
                log.info("S3Controller.downloadFile requestIP:{} fileName:{}, bucketName:{}",request.getRemoteAddr(), fileName, TEST_BUCKET_NAME.bucketName);
            }
            Preconditions.checkArgument(!StringUtils.isEmpty(fileName), "文件名不能为空！");
            Preconditions.checkArgument(!StringUtils.isEmpty(TEST_BUCKET_NAME.bucketName), "对象桶名不能为空！");
            ResponseInputStream<GetObjectResponse> s3Object = fileService.downloadFile(fileName, TEST_BUCKET_NAME.bucketName);
            // 设置HTTP响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
            // 创建InputStreamResource
            InputStreamResource resource = new InputStreamResource(s3Object);
            // 返回下载结果
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(s3Object.response().contentLength())
                    .contentType(MediaType.parseMediaType(s3Object.response().contentType()))
                    .body(resource);
        } catch (Exception e) {
            // 处理异常情况
            return ResponseEntity.status(500).body(null);
        }
    }

    /**
     * 获取文件预签名URL
     */
    @Operation(summary = "获取文件预签名URL")
    @GetMapping("/getUrl")
    public Result<String> getObjectUrl(@RequestParam String fileName) {
        try {
            if (log.isInfoEnabled()) {
                log.info("FileController.getObjectUrl.bucketName:{}, fileName:{}", TEST_BUCKET_NAME.bucketName, fileName);
            }
            Preconditions.checkArgument(!StringUtils.isEmpty(fileName), "文件名不能为空！");
            Preconditions.checkArgument(!StringUtils.isEmpty(TEST_BUCKET_NAME.bucketName), "对象桶名不能为空！");
            return Result.ok(fileService.getFileUrl(TEST_BUCKET_NAME.bucketName, fileName));
        } catch (Exception e) {
            log.error("FileController.getObjectUrl.error:{}", e.getMessage(), e);
            return Result.fail("获取文件预签名URL失败！");
        }
    }

}
